using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using SoapCore;
using System;
using System.Collections.Generic;
using System.ServiceModel.Channels;

namespace KingerRobot.SailunWebService;
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSoapCore();
        var ss = getSoapService();
        foreach (var s in ss)
        {
            services.TryAddSingleton(s.Service, s.Impl);
        }
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            var ss = getSoapService();
            foreach (var s in ss)
            {
                endpoints.UseSoapEndpoint(s.Service, $"/{s.Attribute.PathName}.svc", new SoapEncoderOptions(), SoapSerializer.DataContractSerializer);
                endpoints.UseSoapEndpoint(s.Service, $"/{s.Attribute.PathName}.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer);
            }
        });
    }

    class SoapService
    {
        public Type Service { get; set; }
        public Type Impl { get; set; }
        public SoapServiceAttribute Attribute { get; set; }
    }


    private SoapService[] getSoapService()
    {
        var result = new List<SoapService>();
        var types = this.GetType().Assembly.GetTypes();
        foreach (var type in types)
        {
            if (!type.IsInterface)
            {
                continue;
            }
            var attributes = type.GetCustomAttributes(true);
            foreach (var attribute in attributes)
            {
                var a = attribute as SoapServiceAttribute;
                if (a == null)
                {
                    continue;
                }
                var impl = getServiceImpl(type);
                if (impl == null)
                {
                    continue;
                }
                result.Add(new SoapService
                {
                    Attribute = a,
                    Service = type,
                    Impl = impl,
                });
            }
        }
        return result.ToArray();

    }
    private Type getServiceImpl(Type service)
    {
        var types = this.GetType().Assembly.GetTypes();
        foreach (var type in types)
        {
            if (!type.IsClass)
            {
                continue;
            }
            if (service.IsAssignableFrom(type))
            {
                return type;
            }
        }
        return null;
    }
}